﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Thrift.IL
{
    /// <summary>
    /// 多线程工作任务
    /// </summary>
    public class WorkOfTask
    {
        public WorkOfTask(
            int maxThreadCount,
            Func<int, bool> processTask)
            : this(maxThreadCount, processTask, null)
        {

        }
        public WorkOfTask(
            int maxThreadCount,
            Func<int, bool> processTask,
            Action successTask)
        {
            if (maxThreadCount > 2048)
                throw new ArgumentException("最大线程数不能超过2048个");

            this._maxThreadCount = maxThreadCount;
            this._processTask = processTask;
            this._successTask = successTask;
        }
        /// <summary>
        /// 终止事件
        /// </summary>
        private event Action OnExit;
        /// <summary>
        /// 线程池
        /// </summary>
        private readonly List<Thread> ThreadCollection = new List<Thread>();
        /// <summary>
        /// 任务中产生的最大线程数
        /// </summary>
        private readonly int _maxThreadCount;
        private readonly Action _successTask;
        /// <summary>
        /// 线程核心代码
        /// </summary>
        private readonly Func<int, bool> _processTask;
        /// <summary>
        /// 要做的事，及終止事件
        /// </summary>
        private void TaskRun()
        {
            while (true)
            {
                Monitor.Enter(this);//锁定，保持同步     

                #region 任务块
                var res = _processTask(Thread.CurrentThread.ManagedThreadId);
                #endregion

                #region 任务终于事件触发
                if (res)
                {
                    OnExit();
                }
                #endregion

                Monitor.Exit(this);//取消锁定        
            }
        }

        /// <summary>
        /// 建立線程池子,订阅线程终止条件
        /// </summary>
        private void CreateThreadPool()
        {
            //控制純種
            for (int i = 0; i < _maxThreadCount; i++)
            {
                Thread mythread = new Thread(TaskRun);
                mythread.Name = string.Format("{0}", i);
                ThreadCollection.Add(mythread);
            }
            OnExit += () =>
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("任务队列已经执行完成！");

                if (this._successTask != null)
                    this._successTask();

                foreach (Thread thread in ThreadCollection)
                {
                    thread.Abort();
                }
            };
        }

        public void Action()
        {
            CreateThreadPool();
            foreach (Thread thread in ThreadCollection)
            {
                thread.Start();
            }
        }
    }
}
